/**
 * 
 */
package net.mikoo.seals.agent.biz.services.impl;

import java.math.BigDecimal;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import net.mikoo.seals.agent.biz.mapper.agent.PartyMapper;
import net.mikoo.seals.agent.biz.mapper.agent.PersonMapper;
import net.mikoo.seals.agent.biz.mapper.agent.UserLoginMapper;
import net.mikoo.seals.agent.biz.services.UserLoginServices;
import net.mikoo.seals.agent.common.BaseServices;
import net.mikoo.seals.agent.common.WebContext;
import net.mikoo.seals.agent.common.enums.MobileStatusEnum;
import net.mikoo.seals.agent.common.enums.PartyStatusEnum;
import net.mikoo.seals.agent.common.enums.PartyTypeEnum;
import net.mikoo.seals.agent.common.exception.AccountDisabledException;
import net.mikoo.seals.agent.common.exception.AccountExpiryException;
import net.mikoo.seals.agent.common.exception.AccountFreezedException;
import net.mikoo.seals.agent.common.exception.AccountNotFindException;
import net.mikoo.seals.agent.common.exception.ParametersException;
import net.mikoo.seals.agent.common.exception.PasswordErrorException;
import net.mikoo.seals.agent.common.utils.IPUtil;
import net.mikoo.seals.agent.common.utils.MD5Util;
import net.mikoo.seals.agent.common.utils.ValidatorUtil;
import net.mikoo.seals.agent.model.Party;
import net.mikoo.seals.agent.model.Person;
import net.mikoo.seals.agent.model.UserLogin;
import net.mikoo.seals.agent.model.UserLoginHistory;

/**
 * @author huangxm
 * 
 */
public class UserLoginServicesImpl extends BaseServices implements UserLoginServices {
	
	Logger logger = Logger.getLogger(UserLoginServicesImpl.class);
	
	@Autowired
	private PartyMapper		partyMapper;
	
	@Autowired
	private UserLoginMapper	userLoginMapper;
	
	@Autowired
	private PersonMapper	personMapper;
	
	
	
	@Override
	public Party authLogin(String username, String password, String partyType){
		
			
			if (StringUtils.isEmpty(username)) {
				throw new ParametersException("登陆账户名不能为空");
			}
			
			if (StringUtils.isEmpty(password)) {
				throw new ParametersException("登陆密码不能为空");
			}
			
			
			//记录登录信息
			UserLoginHistory userLoginHistory = new UserLoginHistory();
			userLoginHistory.setLoginTime(new Date());
			userLoginHistory.setUserLoginId(username);
			userLoginHistory.setPasswordUsed(password);
			userLoginHistory.setLoginIp(IPUtil.getRemoteAddr(WebContext.getRequest()));
			
			
			//如果用户名为空则查询用户手机号
			UserLogin userLogin = userLoginMapper.selectByUserLoginId(username);
			if (userLogin == null) {
				
				//邮箱登录
				Person ePerson = personMapper.selectByEmail(username);
				if (ePerson == null) {
					//手机号码登录
					Person mPerson = personMapper.selectByMobile(username);
					if (mPerson == null) {
						//记录登录失败原因
						userLoginHistory.setResults("登陆账户不存在");
						userLoginHistory.setSuccessfulLogin("N");
						recordLoginHistory(userLoginHistory);
						//返回错误信息
						//result.setResult(false,Result.USERNAME_NOT_EXISTS,"登陆账户不存在");
						throw new AccountNotFindException("登陆账户不存在");
					} 
				} 
				
				userLogin = userLoginMapper.selectByUserLoginId(ePerson.getUserLoginId());
			} 
				
			//判断当事人类型
			Party party = partyMapper.selectByPartyType(userLogin.getPartyId(), partyType);
			//Party party = partyMapper.selectByPrimaryKey(userLogin.getPartyId());
			if (party == null) {
				userLoginHistory.setResults("登陆账户不存在");
				userLoginHistory.setSuccessfulLogin("N");
				recordLoginHistory(userLoginHistory);
				
				throw new AccountNotFindException("登陆账户不存在");
			}
			
			//判断登录帐户是否禁用
			String enabled = userLogin.getEnabled();
			if (enabled.equals("N")) {
				userLoginHistory.setResults("账户已被禁用");
				userLoginHistory.setSuccessfulLogin("N");
				recordLoginHistory(userLoginHistory);
				throw new AccountDisabledException("账户已被禁用");
			}
			
			//判断帐户是否被冻结
			if (party.getPartyStatus().equals("FREEZE")) {
				userLoginHistory.setResults("账户已被冻结");
				userLoginHistory.setSuccessfulLogin("N");
				recordLoginHistory(userLoginHistory);
				//result.setResult(false,Result.USERNAME_freezed,"账户已被冻结");
				throw new AccountFreezedException("账户已被冻结");
			}
			
			//判断帐户是否过期
			if (party.getExpiryDate() != null && party.getExpiryDate().before(new Date())) {
				userLoginHistory.setResults("账户已过期");
				userLoginHistory.setSuccessfulLogin("N");
				recordLoginHistory(userLoginHistory);
				//result.setResult(false,Result.USERNAME_EXPIRY,"账户已过期");
				throw new AccountExpiryException("账户已过期");
			}
			
			//判断密码是否正确
			String currentPassword = userLogin.getCurrentPassword();
			if (!MD5Util.Md5(password).equals(currentPassword)) {
				userLoginHistory.setResults("登陆密码错误");
				userLoginHistory.setSuccessfulLogin("N");
				recordLoginHistory(userLoginHistory);
				//result.setResult(false,Result.PASSWORD_ERROR,"登陆密码错误");
				throw new PasswordErrorException("登陆密码错误");
			}
			
			userLoginHistory.setSuccessfulLogin("Y");
			userLoginHistory.setResults("login success");
			recordLoginHistory(userLoginHistory);
			
			
			userLogin.setLastLoginIp(userLogin.getCurrentLoginIp());
			userLogin.setLastLoginTime(userLogin.getCurrentLoginTime());
			userLogin.setCurrentLoginIp(IPUtil.getRemoteAddr(WebContext.getRequest()));
			userLogin.setCurrentLoginTime(new Date());
			userLogin.setLoginTimes(userLogin.getLoginTimes()==null?new BigDecimal("1"):userLogin.getLoginTimes().add(new BigDecimal("1")));
			
			userLoginMapper.updateByPrimaryKey(userLogin);
			
			
			return party;
	}
	
	public void recordLoginHistory(UserLoginHistory userLoginHistory) {
		userLoginMapper.insertHistory(userLoginHistory);
	}
	
	@Override
	public void changePassword(String username,String newPassword,String oldPassword) {
		
			
			if (StringUtils.isBlank(username)) {
				throw new ParametersException("用户名不能为空");
			}
			
			
			if (StringUtils.isBlank(newPassword)) {
				throw new ParametersException("新密码不能为空");
			}
			
			UserLogin userLogin = userLoginMapper.selectByUserLoginId(username);
			if(userLogin == null){
				throw new ParametersException("用户名不存在");
			}
			
			if(!MD5Util.Md5(oldPassword).equals(userLogin.getCurrentPassword())){
				throw new ParametersException("旧密码输入不正确");
			}
			
			userLogin.setCurrentPassword(MD5Util.Md5(newPassword));
			userLoginMapper.updateByPrimaryKey(userLogin);
			
	}
	
	@Override
	public void resetPassword(String username, String newPassword) {

		if (StringUtils.isBlank(username)) {
			throw new ParametersException("手机号码不能为空");
		}

		if (!ValidatorUtil.isMobile(username)) {
			throw new ParametersException("手机号码输入有误");
		}

		if (StringUtils.isBlank(newPassword)) {
			throw new ParametersException("新密码不能为空");
		}

		UserLogin userLogin = userLoginMapper.selectByUserLoginId(username);
		if (userLogin == null) {
			throw new ParametersException("用户名不存在");
		}

		userLogin.setCurrentPassword(MD5Util.Md5(newPassword));
		userLoginMapper.updateByPrimaryKey(userLogin);

	}
	
	@Override
	public boolean isRightByPassword(String userLoginId, String currentPassword) {
		
		UserLogin userLogin = userLoginMapper.selectByUserLoginId(userLoginId);
		if (userLogin.getCurrentPassword().equals(currentPassword)) {
			
			return true;
		}
		return false;
	}
	
	@Override
	public UserLogin loadByPrimaryKey(String userLoginId) {
		
		return userLoginMapper.selectByUserLoginId(userLoginId);
	}


	@Override
	public void deleteByPartyId(Long partyId) {

		if (partyId == null) {
			throw new ParametersException("partyId is null!");
		}
		// 打印执行参数日志
		userLoginMapper.deleteByPartyId(partyId);

	}


	@Override
	public void updateByPartyId(UserLogin userLogin) {
		// 打印执行日志
		if (userLogin == null) {
			throw new ParametersException("userLogin is null!");
		}
		// 打印执行参数日志
		userLoginMapper.updateByPrimaryKey(userLogin);

	}
	
	@Override
	public Boolean checkUsernameExist(String verifykey, String excludeKey, String type) {

		if (StringUtils.isBlank(verifykey)) {
			throw new ParametersException("用户名为空");
		}

		if (StringUtils.isBlank(type)) {
			throw new ParametersException("验证关键字类型不能为空！");
		}

		boolean b = isExist(verifykey, excludeKey, type);

		return b;

	}
	
	
	/**
	 * 判断字段是否唯一
	 * @param verifykey
	 * @param excludeKey
	 * @param type
	 * @return
	 */
	private boolean isExist(String verifykey, String excludeKey, String type) {
		boolean b = false;
		switch (type) {
			case "username":
				
				UserLogin userLogin = userLoginMapper.selectByUserLoginId(verifykey);
				if (userLogin == null) {
					b = false;
				} else {
					
					b = true;
					if (StringUtils.isNotBlank(excludeKey)) {
						if (verifykey.equals(userLogin.getUserLoginId())) {
							b = false;
						}
					}
				}
				break;
			
			case "mobile":
				Person mPerson = personMapper.selectByMobile(verifykey);
				if (mPerson == null) {
					b = false;
				} else {
					
					b = true;
					
					if (StringUtils.isNotBlank(excludeKey)) {
						if (verifykey.equals(mPerson.getMobile())) {
							b = false;
						}
					}
				}
				break;
			
			case "email":
				
				Person ePerson = personMapper.selectByEmail(verifykey);
				if (ePerson == null) {
					b = false;
				} else {
					b = true;
					if (StringUtils.isNotBlank(excludeKey)) {
						if (verifykey.equals(ePerson.getEmail())) {
							b = false;
						}
					}
				}
				
				break;
			default:
				
				break;
		}
		
		return b;
	}

	
	@Override
	public Party register(final String username, final String password) {

		return bossTransactionTemplate.execute(new TransactionCallback<Party>() {

			@Override
			public Party doInTransaction(TransactionStatus status) {

				if (StringUtils.isBlank(username)) {
					throw new ParametersException("手机号码不能为空");
				}

				if (!ValidatorUtil.isMobile(username)) {
					throw new ParametersException("手机号码输入有误");
				}

				// 验证密码字段
				if (StringUtils.isBlank(password)) {
					throw new ParametersException("登陆密码为空");
				}

				boolean usernameExist = isExist(username, null, "username");
				if (usernameExist) {
					throw new ParametersException("该登陆账户已存在");
				}

				boolean mobileExist = isExist(username, null, "mobile");
				if (mobileExist) {
					throw new ParametersException("该手机号码已存在");
				}

				Party party = new Party();
				party.setPartyType(PartyTypeEnum.AGETN.code());
				party.setPartyStatus(PartyStatusEnum.NORMAL.code());
				party.setUserLoginId(username);
				party.setCreatedTime(new Date());
				partyMapper.insertBackPrimaryKey(party);

				// 创建登录帐户
				UserLogin userLogin = new UserLogin();
				userLogin.setUserLoginId(username);
				userLogin.setPartyId(party.getPartyId());
				userLogin.setCurrentPassword(MD5Util.Md5(password));
				userLogin.setIsSystem("Y");
				userLogin.setEnabled("Y");
				userLogin.setRequirePasswordChange("N");
				userLogin.setRegisterTime(new Date());
				userLogin.setRegisterIp(IPUtil.getRemoteAddr(WebContext.getRequest()));
				userLoginMapper.insert(userLogin);

				// 创建人员信息
				Person person = new Person();
				person.setUserLoginId(username);
				person.setPartyId(party.getPartyId());
				person.setMobile(username);
				person.setMobileStatus(MobileStatusEnum.CERTIFIED.code());
				personMapper.insert(person);

				party.setUserLogin(userLogin);
				party.setPerson(person);

				return party;

			}
		});
	}
	
	
	public static void main(String[] args) {
		System.out.println(MD5Util.Md5("111111"));
	}
}
